package stars;

import gameAppLayer.enums.Constants;

import java.util.ArrayList;
import java.util.Random;
import java.util.logging.Level;
import java.util.logging.Logger;

import model.PhysicalDataModel;
import modifiers.Feature;
import modifiers.IModifier;

import stars.enums.StarParameters;
import stars.enums.StarTypeData;
import testClasses.misc.TestTextureCoords;

/*
 * Creates a starModel object
 * Input: Temperature, star type
 * Output: starModel
 * 
*/
public class StarModelBuilder {
	private static final Logger logger = Logger.getLogger(StarModelBuilder.class.getName());
//	private final double lumSun = Constants.SunLumWatts;  //luminosity of sun
//	private final double radiusSun = Constants.SunRadiusMeters; //radius in m
//	private final double massSun = Constants.SunMassKg; //kg
	//converts solar masses, solar radii into kg, m for gravity calculation
//	private final double mr2Sun = Constants.SunMassKg/Constants.SunRadiusMeters/Constants.SunRadiusMeters; 
	
//	private final double sigma = Constants.BoltzmannConstant;  //Boltzmann's constant (W/m2/K4)
//	private final double gravConstant = Constants.GravitationalConstant; //m3/kg/s2
//	private final double earthGrav = Constants.EarthGravity; //m/s2
	
	//Constants for equations developing main sequence, giants, and supergiants
	//Zaninetti (2008)
//	private final double kbvMain = -0.641;
//	private final double tbvMain = 7360.0;
//	private final double kbvGiant = -0.792;
//	private final double tbvGiant = 8527.0;
//	private final double kbvSuperG = -0.749;
//	private final double tbvSuperG = 8261.0;
	
	private final double amtMain = -7.769;
	private final double bmtMain = 0.8972;
	private final double amtGiant = 10.41;
	private final double bmtGiant = -1.167;
	private final double amtSuperGHigh = 3.73;
	private final double bmtSuperGHigh = -0.2801;
	private final double amtSuperGLow = 0.20;
	private final double bmtSuperGLow = 0.1276;
	
	private final double almMain = -26.63;
	private final double blmMain = 3.083;
	private final double almGiant = 29.469; //0.32;
	private final double blmGiant = -3.2676; //2.79;
	private final double almSuperGLow = 1.7881; //1.29;
	private final double blmSuperGLow = 0.3112; //2.43;	
	private final double almSuperGHigh = 10.392; 
	private final double blmSuperGHigh = -0.682; 
	
	private final double armMain = -5.793;
	private final double brmMain = 0.6729;
//	private final double armGiant = 22.25; //0.32;
//	private final double brmGiant = -2.502; //2.79;
//	private final double armSuperGLow = 8.417; //1.29;
//	private final double brmSuperGLow = -0.7129; //2.43;	
//	private final double armSuperGHigh = 12.71; 
//	private final double brmSuperGHigh = -1.21;	
	
	//Constants for white dwarf equations (not currently used)
//	private final double kbvWhite = -0.4693058;
//	private final double tbvWhite = 6466.229;
//	private final double kbcWhite = 42.61225;
//	private final double tbcWhite = 29154.75;
//	private final double almWhite = 0.28;
//	private final double blmWhite = 2.29;
//	private final double amtWhite = -7.80;
//	private final double bmtWhite = 1.61;
	
	private Random rand = new Random();
//	private StarParameters starParams;
//	private StarColors starColors;
	
	public ArrayList<Feature> features = new ArrayList<Feature>(); //lists names of all modifiers to be applied
	
	public StarModelBuilder(){}
	
	public StarModel createMStar(double temp, String type, StarParameters starParams)
	{
		StarModel star = new StarModel();
		PhysicalDataModel physModel = star.getPhysicalDataModel();
		//star.setLocation(coordinate.getLocation());		
		star.setType(type);
		star.getPhysicalDataModel().setTemperature(temp);
		
		if (type.equalsIgnoreCase("WHITEDWARF")) {
			createWhiteDwarf(star, physModel, starParams);
		}
		else if (type.toUpperCase().contains("RGT")) { //.equalsIgnoreCase("GIANT")) {
			createGiant(star, physModel, starParams);
		}
		else if (type.toUpperCase().contains("SGT")) {
			createSuperGiant(star, physModel, starParams);
		}
		else if (type.toUpperCase().contains("HGT")) {
			createHyperGiant(star, physModel, starParams);
		}
		else if (type.equalsIgnoreCase("NEUTRON")) {
			createNeutron(star, physModel, starParams);
		}
		else if (type.equalsIgnoreCase("BLACKHOLE")) {
			createBlackhole(star, physModel, starParams);
		}
		else if (type.equalsIgnoreCase("T_TAURI")) {
			createTTauri(star, physModel, starParams);
		}
		else if (type.toUpperCase().contains("MS")){ 
			createMainSequence(star, physModel, starParams);
		}
		else {
			logger.log(Level.INFO, "Star type not recognized!");
		}
		
		return star;
	}

	private void createBlackhole(StarModel star, PhysicalDataModel physModel, StarParameters starParams) {
		String type = star.getType();
		StarTypeData data = starParams.getAllParameters().get(type);
		
		star.setColorName("Black");
		
		physModel.setLuminosity(data.getMaxLuminance()*Constants.SunLumWatts);
		
		//3.8 - 15 solar masses
		double minMass = data.getMinMass();
		double maxMass = data.getMaxMass();
		double massRange = maxMass - minMass; 
		physModel.setMass((rand.nextDouble()*massRange+minMass)*Constants.SunMassKg);		
		physModel.setRadius(2.95*physModel.getMass()/Constants.SunMassKg);
		
		physModel.setRotation(getRotation(data));
		physModel.setMagField(getMagField(data));
		//star.setGravity(getGravity(star.getMass(), star.getRadius()));//Gs
		star.setLifetime(13000000000.0);  //yrs
		
		physModel.setAge(getAge(star.getLifetime()));
		
		//star.setStability(getStability(data));
	}

	private void createNeutron(StarModel star, PhysicalDataModel physModel, StarParameters starParams) {
		String type = star.getType();
		StarTypeData data = starParams.getAllParameters().get(type);
		
		star.setColorName("Magenta");
		
		physModel.setLuminosity(data.getMaxLuminance()*Constants.SunLumWatts);
		
		//1.35 - 2.0 solar masses
		double minMass = data.getMinMass();
		double maxMass = data.getMaxMass();
		double massRange = maxMass - minMass;
		physModel.setMass((rand.nextDouble()*massRange+minMass)*Constants.SunMassKg);
		
		//~12 km
		double minRad = data.getMinRadius();
		double maxRad = data.getMaxRadius();
		double radRange = maxRad - minRad;
		physModel.setRadius((rand.nextDouble()*radRange+minRad)*Constants.SunRadiusKilometers);
		
		physModel.setRotation(getRotation(data));
		physModel.setMagField(getMagField(data));
		//star.setGravity(getGravity(star.getMass(), star.getRadius()));//Gs
		star.setLifetime(13000000000.0);  //yrs //Note, Neutron stars can probably live trillions of years
		physModel.setAge(getAge(star.getLifetime()));
		
		//star.setStability(getStability(data));		
	}

	private void createTTauri(StarModel star, PhysicalDataModel physModel, StarParameters starParams) {
		String type = star.getType();
		StarTypeData data = starParams.getAllParameters().get(type);
		
		double mass = Math.pow(10, amtMain + bmtMain*Math.log(physModel.getTemperature()))*Constants.SunMassKg;
		physModel.setMass(mass);
		
		double lumFactor = rand.nextDouble()*10+5; //5x to 15x brighter than normal
		double lum = lumFactor*Math.pow(10, almMain + blmMain*Math.log(physModel.getTemperature()))*Constants.SunLumWatts;
		physModel.setLuminosity(lum);
		
		double radius = Math.pow(10, (armMain + brmMain*Math.log(physModel.getTemperature())))*Constants.SunRadiusKilometers;
		physModel.setRadius(radius);
		
		star.setColorName(getColor(physModel.getTemperature(), starParams));
		star.setLifetime(rand.nextDouble()*100000000.0 + 1000000);  //1 - 100 million yrs.
		
		physModel.setAge(getAge(star.getLifetime()));
		
		//star.setGravity(getGravity(star.getMass(), star.getRadius()));//Gs
		
		physModel.setRotation(getRotation(data));
		physModel.setMagField(getMagField(data));
		
		//star.setStability(getStability(data));
	}

	private void createHyperGiant(StarModel star, PhysicalDataModel physModel, StarParameters starParams) {
		String type = star.getType();
		StarTypeData data = starParams.getAllParameters().get(type);
		
		double minRad = data.getMinRadius();
		double maxRad = data.getMaxRadius();
		double radRange = maxRad - minRad;
		double minTemp = data.getMinTemp();
		double maxTemp = data.getMaxTemp();
		double radius = ((1-(physModel.getTemperature()-minTemp)/(maxTemp - minTemp))*radRange+minRad)*Constants.SunRadiusKilometers;
		physModel.setRadius(radius); 

		star.setColorName(getColor(physModel.getTemperature(), starParams));
		star.setLifetime(3000000.0);
		
		double minLum = data.getMinLuminance();
		double maxLum = data.getMaxLuminance();
		double lumRange = maxLum - minLum;
		double luminosity = ((physModel.getTemperature()-minTemp)/(maxTemp - minTemp)*lumRange+minLum)*Constants.SunLumWatts;
		physModel.setLuminosity(luminosity);
		
		physModel.setAge(getAge(star.getLifetime()));
		
		double minMass = data.getMinMass();
		double maxMass = data.getMaxMass();
		double massRange = maxMass - minMass;
		physModel.setMass((rand.nextDouble()*massRange+minMass)*Constants.SunMassKg); //solar mass
		//star.setGravity(getGravity(star.getMass(), star.getRadius()));//Gs
		
		physModel.setRotation(getRotation(data));
		physModel.setMagField(getMagField(data));
		
		//star.setStability(getStability(data));		
		
	}

	private void createSuperGiant(StarModel star, PhysicalDataModel physModel, StarParameters starParams) {
		String type = star.getType();
		StarTypeData data = starParams.getAllParameters().get(type);		
		
		double minRad = data.getMinRadius();
		double maxRad = data.getMaxRadius();
		double radRange = maxRad - minRad;
		double minTemp = data.getMinTemp();
		double maxTemp = data.getMaxTemp();
		double radius = ((1-(physModel.getTemperature()-minTemp)/(maxTemp - minTemp))*radRange+minRad)*Constants.SunRadiusKilometers;
		physModel.setRadius(radius); 
				
		double minLum = data.getMinLuminance();
		double maxLum = data.getMaxLuminance();
		double lumRange = maxLum - minLum;
		double luminosity = ((physModel.getTemperature()-minTemp)/(maxTemp - minTemp)*lumRange+minLum)*Constants.SunLumWatts;
		physModel.setLuminosity(luminosity);
		
		double minMass = data.getMinMass();
		double maxMass = data.getMaxMass();
		double massRange = maxMass - minMass;
		physModel.setMass((rand.nextDouble()*massRange+minMass)*Constants.SunMassKg); //solar mass
		
		
		
//		if (star.getTemperature() > 5474) {
//			mass = Math.pow(10, amtSuperGHigh + bmtSuperGHigh*Math.log(star.getTemperature()));
//			//CHANGE THIS TO SAME PROCEDURE AS HYPERGIANT
//			double minRad = data.getMinRadius();
//			double maxRad = data.getMaxRadius();
//			double radRange = maxRad - minRad;
//			double minTemp = data.getMinTemp();
//			double maxTemp = data.getMaxTemp();
//			radius = ((1-(star.getTemperature()-minTemp)/(maxTemp - minTemp))*radRange+minRad);
//			//radius = Math.pow(10, (armSuperGHigh - brmSuperGHigh*Math.log(star.getTemperature())));
//			lum = Math.pow(10, almSuperGHigh + blmSuperGHigh*Math.log(star.getTemperature()));
//		}
//		else {
//			mass = Math.pow(10, amtSuperGLow + bmtSuperGLow*Math.log(star.getTemperature()));
//			//CHANGE THIS TO SAME PROCEDURE AS HYPERGIANT
//			double minRad = data.getMinRadius();
//			double maxRad = data.getMaxRadius();
//			double radRange = maxRad - minRad;
//			double minTemp = data.getMinTemp();
//			double maxTemp = data.getMaxTemp();
//			radius = ((star.getTemperature()-minTemp)/(maxTemp - minTemp)*radRange+minRad);
//			//radius = Math.pow(10, (armSuperGLow - brmSuperGLow*Math.log(star.getTemperature())));
//			lum = Math.pow(10, almSuperGLow + blmSuperGLow*Math.log(star.getTemperature()));
//		}			
		star.setColorName(getColor(physModel.getTemperature(), starParams));
		
		star.setLifetime(Math.pow((physModel.getMass()/Constants.SunMassKg), -2.5)*Math.pow(10, 10));
		
		physModel.setAge(getAge(star.getLifetime()));
		
	//	star.setGravity(getGravity(star.getMass(), star.getRadius()));//Gs
		
		physModel.setRotation(getRotation(data));
		physModel.setMagField(getMagField(data));
		
		//star.setStability(getStability(data));		
	}

	private void createGiant(StarModel star, PhysicalDataModel physModel, StarParameters starParams) {
		String type = star.getType();
		StarTypeData data = starParams.getAllParameters().get(type);
		
		double mass = 0.0;
		//mass = Math.pow(10, amtGiant + -2.68*Math.log10(star.getTemperature()))*Constants.SunMassKg;
		mass = Math.pow(10, amtGiant + bmtGiant*Math.log(physModel.getTemperature()))*Constants.SunMassKg;
		physModel.setMass(mass);
		
		double lum = 0.0;
		lum = Math.pow(10, almGiant+ blmGiant*Math.log(physModel.getTemperature()))*Constants.SunLumWatts;
		physModel.setLuminosity(lum);
		
		//QQQ CHANGE THIS TO SAME PROCEDURE AS HYPERGIANT
		double minRad = data.getMinRadius();
		double maxRad = data.getMaxRadius();
		double radRange = maxRad - minRad;
		double minTemp = data.getMinTemp();
		double maxTemp = data.getMaxTemp();
		double radius = ((1-(physModel.getTemperature()-minTemp)/(maxTemp - minTemp))*radRange+minRad)*Constants.SunRadiusKilometers;
		
		//double radius = 0.0;
		//radius = Math.pow(10, (armGiant - brmGiant*Math.log(star.getTemperature())))*Constants.SunRadiusKilometers;
		physModel.setRadius(radius);
		
		star.setColorName(getColor(physModel.getTemperature(), starParams));
		
		star.setLifetime(Math.pow((physModel.getMass()/Constants.SunMassKg), -2.5)*Math.pow(10, 10));
		
		physModel.setAge(getAge(star.getLifetime()));
		
		//star.setGravity(getGravity(star.getMass(), star.getRadius()));//Gs
		
		physModel.setRotation(getRotation(data));
		physModel.setMagField(getMagField(data));
		
		//star.setStability(getStability(data));		
	}

	private void createMainSequence(StarModel star, PhysicalDataModel physModel, StarParameters starParams) {
		String type = star.getType();
		StarTypeData data = starParams.getAllParameters().get(type);
		
		double mass = Math.pow(10, amtMain + bmtMain*Math.log(physModel.getTemperature()))*Constants.SunMassKg;
		physModel.setMass(mass);
		
		double lum = Math.pow(10, almMain + blmMain*Math.log(physModel.getTemperature()))*Constants.SunLumWatts;		
		physModel.setLuminosity(lum);
		
		double radius = Math.pow(10, (armMain + brmMain*Math.log(physModel.getTemperature())))*Constants.SunRadiusKilometers;
		physModel.setRadius(radius);
		
		star.setColorName(getColor(physModel.getTemperature(), starParams));
		
		star.setLifetime(Math.pow((1.0/(physModel.getLuminosity()/Constants.SunLumWatts)), (5.0/7.0))*10000000000.0);  //yrs
		
		physModel.setAge(getAge(star.getLifetime()));
		
		//star.setGravity(getGravity(star.getMass(), star.getRadius()));//Gs
		
		physModel.setRotation(getRotation(data));
		physModel.setMagField(getMagField(data));
		
		//star.setStability(getStability(data));
		
	}

	private void createWhiteDwarf(StarModel star, PhysicalDataModel physModel, StarParameters starParams) {
		String type = star.getType();
		StarTypeData data = starParams.getAllParameters().get(type);
		
		double mass = 0.0;
		mass = Math.pow(10, (-7.799 + 0.6992*Math.log(physModel.getTemperature())))*Constants.SunMassKg;
		physModel.setMass(mass);
		
		double lum = 0.0;
		lum = Math.pow(10, (-17.58 + 1.601*Math.log(physModel.getTemperature())))*Constants.SunLumWatts;
		physModel.setLuminosity(lum);
		
		double radius = 0.0;
		radius = Math.pow(10, (-1.267 - 0.0679*Math.log(physModel.getTemperature())))*Constants.SunRadiusKilometers; 
		physModel.setRadius(radius);		
		
		star.setColorName(starParams.getColorName(type));
		
		star.setLifetime(Constants.AgeOfUniverse); //yrs
		
		physModel.setAge(getAge(star.getLifetime()));
		
		//star.setGravity(getGravity(star.getMass(), star.getRadius()));//Gs
		
		physModel.setRotation(getRotation(data));
		physModel.setMagField(getMagField(data));
		
		//star.setStability(getStability(data));		
		
	}
	
	
//	private double getGravity(double massStar, double radiusStar)
//	{
//		double grav = 0.0;
//		
//		radiusStar = radiusStar*1000; //change from km to m
//		grav = gravConstant*massStar/radiusStar/radiusStar/earthGrav;
//		return grav;		
//	}
	
	
	private String getColor(double temperature, StarParameters starParams)
	{
		ArrayList<Integer> errorColor = new ArrayList<Integer>();
		errorColor.add(255); errorColor.add(20); errorColor.add(147); //Bright pink shows error
		
		
		ArrayList<String> entries = starParams.getEntries();
		//String name;
		//String nameStart; //first two letters of name
		for (String entry : entries) {
			//name = starParams.getParameter(entry).getName();
			if (entry.substring(0,2).equalsIgnoreCase("MS")) { //only compare to main sequence stars
				if (temperature > starParams.getParameter(entry).getMinTemp() && 
						(temperature <= starParams.getParameter(entry).getMaxTemp())) {
					return starParams.getColorName(entry);
				}				
			}			
		}
		
		return "Pink"; //haven't found anything within temperature bounds, so return error color
		
		
		
//		if (temperature > EStarType.MS_BLUE.getMinTemp())
//			return EStarColor.BLUE;
//		else if ((temperature <= EStarType.MS_BLUEWHITE.getMaxTemp()) && (temperature > EStarType.MS_BLUEWHITE.getMinTemp()))
//			return EStarColor.BLUEWHITE;
//		else if ((temperature <= EStarType.MS_WHITE.getMaxTemp()) && (temperature > EStarType.MS_WHITE.getMinTemp()))
//			return EStarColor.WHITE;
//		else if ((temperature <= EStarType.MS_YELLOWWHITE.getMaxTemp()) && (temperature > EStarType.MS_YELLOWWHITE.getMinTemp()))
//			return EStarColor.YELLOWWHITE;
//		else if ((temperature <= EStarType.MS_YELLOW.getMaxTemp()) && (temperature > EStarType.MS_YELLOW.getMinTemp()))
//			return EStarColor.YELLOW;
//		else if ((temperature <= EStarType.MS_ORANGE.getMaxTemp()) && (temperature > EStarType.MS_ORANGE.getMinTemp()))
//			return EStarColor.ORANGE;
//		else if (temperature <= EStarType.MS_RED.getMaxTemp())
//			return EStarColor.RED;
//		else
//			return EStarColor.BLACK;
	}
	
	//stellar rotation varies by stellar type
	//http://en.wikipedia.org/wiki/Stellar_rotation
	private double getRotation(StarTypeData data)
	{
		//double mag = Math.pow(10, -5);
		double rotMax = data.getMaxRotation();
		double rotMin = data.getMinRotation();
		double rotRange = rotMax - rotMin;
		double rotation = (rand.nextDouble()*rotRange+rotMin); //rad/s;
		
		return rotation;
		
//		switch (type) {
//		case MS_BLUE:
//			rotMax = EStarType.MS_BLUE.getMaxRotate();
//			rotMin = EStarType.MS_BLUE.getMinRotate();
//			rotRange = rotMax - rotMin;
//			rotation = (rand.nextDouble()*rotRange+rotMin); //rad/s
//			break;
//		case MS_BLUEWHITE:
//			rotMax = EStarType.MS_BLUEWHITE.getMaxRotate();
//			rotMin = EStarType.MS_BLUEWHITE.getMinRotate();
//			rotRange = rotMax - rotMin;
//			rotation = (rand.nextDouble()*rotRange+rotMin); //rad/s
//			break;
//		case MS_WHITE:
//			rotMax = EStarType.MS_WHITE.getMaxRotate();
//			rotMin = EStarType.MS_WHITE.getMinRotate();
//			rotRange = rotMax - rotMin;
//			rotation = (rand.nextDouble()*rotRange+rotMin); //rad/s
//			break;
//		case MS_YELLOWWHITE:
//			rotMax = EStarType.MS_YELLOWWHITE.getMaxRotate();
//			rotMin = EStarType.MS_YELLOWWHITE.getMinRotate();
//			rotRange = rotMax - rotMin;
//			rotation = (rand.nextDouble()*rotRange+rotMin); //rad/s
//			break;
//		case MS_YELLOW:
//			rotMax = EStarType.MS_YELLOW.getMaxRotate();
//			rotMin = EStarType.MS_YELLOW.getMinRotate();
//			rotRange = rotMax - rotMin;
//			rotation = (rand.nextDouble()*rotRange+rotMin); //rad/s
//			break;
//		case MS_ORANGE:
//			rotMax = EStarType.MS_ORANGE.getMaxRotate();
//			rotMin = EStarType.MS_ORANGE.getMinRotate();
//			rotRange = rotMax - rotMin;
//			rotation = (rand.nextDouble()*rotRange+rotMin); //rad/s
//			break;
//		case MS_RED:
//			rotMax = EStarType.MS_RED.getMaxRotate();
//			rotMin = EStarType.MS_RED.getMinRotate();
//			rotRange = rotMax - rotMin;
//			rotation = (rand.nextDouble()*rotRange+rotMin); //rad/s
//			break;
//		case T_TAURI:
//			//T_Tauri stars rotate between 2x and 30x faster than equiv. main seq.
//			//http://en.wikipedia.org/wiki/T_Tauri_star
//			double adjust = rand.nextDouble()*28.0+2.0;
//			switch(color) {
//			case BLUE:
//				rotMax = EStarType.MS_BLUE.getMaxRotate();
//				rotMin = EStarType.MS_BLUE.getMinRotate();
//				rotRange = rotMax - rotMin;
//				rotation = adjust*(rand.nextDouble()*rotRange+rotMin); //rad/s
//				break;
//			case BLUEWHITE:
//				rotMax = EStarType.MS_BLUEWHITE.getMaxRotate();
//				rotMin = EStarType.MS_BLUEWHITE.getMinRotate();
//				rotRange = rotMax - rotMin;
//				rotation = adjust*(rand.nextDouble()*rotRange+rotMin); //rad/s
//				break;
//			case WHITE:
//				rotMax = EStarType.MS_WHITE.getMaxRotate();
//				rotMin = EStarType.MS_WHITE.getMinRotate();
//				rotRange = rotMax - rotMin;
//				rotation = adjust*(rand.nextDouble()*rotRange+rotMin); //rad/s
//				break;
//			case YELLOWWHITE:
//				rotMax = EStarType.MS_YELLOWWHITE.getMaxRotate();
//				rotMin = EStarType.MS_YELLOWWHITE.getMinRotate();
//				rotRange = rotMax - rotMin;
//				rotation = adjust*(rand.nextDouble()*rotRange+rotMin); //rad/s
//				break;
//			case YELLOW:
//				rotMax = EStarType.MS_YELLOW.getMaxRotate();
//				rotMin = EStarType.MS_YELLOW.getMinRotate();
//				rotRange = rotMax - rotMin;
//				rotation = adjust*(rand.nextDouble()*rotRange+rotMin); //rad/s
//				break;
//			case ORANGE:
//				rotMax = EStarType.MS_ORANGE.getMaxRotate();
//				rotMin = EStarType.MS_ORANGE.getMinRotate();
//				rotRange = rotMax - rotMin;
//				rotation = adjust*(rand.nextDouble()*rotRange+rotMin); //rad/s
//				break;
//			case RED:
//				rotMax = EStarType.MS_RED.getMaxRotate();
//				rotMin = EStarType.MS_RED.getMinRotate();
//				rotRange = rotMax - rotMin;
//				rotation = adjust*(rand.nextDouble()*rotRange+rotMin); //rad/s
//				break;
//			default:
//				rotation = 0.0;
//			}
//			break;
//		case NEUTRON:
//			rotation = rand.nextDouble()*EStarType.NEUTRON.getMaxRotate(); //rad/s
//			break;
//		case BLACKHOLE:
//			rotation = rand.nextDouble()*EStarType.BLACKHOLE.getMaxRotate(); //rad/s
//			break;
//		case HYPERGIANT:
//			rotMax = EStarType.MS_ORANGE.getMaxRotate();
//			rotMin = EStarType.MS_ORANGE.getMinRotate();
//			rotRange = rotMax - rotMin;
//			rotation = (rand.nextDouble()*rotRange+rotMin); //rad/s
//			break;
//		case SUPERGIANT:
//			rotMax = EStarType.MS_ORANGE.getMaxRotate();
//			rotMin = EStarType.MS_ORANGE.getMinRotate();
//			rotRange = rotMax - rotMin;
//			rotation = (rand.nextDouble()*rotRange+rotMin); //rad/s
//			break;
//		case GIANT:
//			rotMax = EStarType.MS_ORANGE.getMaxRotate();
//			rotMin = EStarType.MS_ORANGE.getMinRotate();
//			rotRange = rotMax - rotMin;
//			rotation = (rand.nextDouble()*rotRange+rotMin); //rad/s
//			break;
//		/*case SUBGIANT:
//			rotMax = StarType.MS_ORANGE.getMaxRotate();
//			rotMin = StarType.MS_ORANGE.getMinRotate();
//			rotRange = rotMax - rotMin;
//			rotation = mag*(rand.nextDouble()*rotRange+rotMin); //rad/s
//			break;
//*/		case DWARF_WHITE:
//			rotMax = EStarType.MS_ORANGE.getMaxRotate();
//			rotMin = EStarType.MS_ORANGE.getMinRotate();
//			rotRange = rotMax - rotMin;
//			rotation = (rand.nextDouble()*rotRange+rotMin); //rad/s
//			break;
//		/*case SUBDWARF:
//			rotMax = StarType.MS_ORANGE.getMaxRotate();
//			rotMin = StarType.MS_ORANGE.getMinRotate();
//			rotRange = rotMax - rotMin;
//			rotation = mag*(rand.nextDouble()*rotRange+rotMin); //rad/s
//			break;
//*/		default:
//			rotation = 0.0;
//		}
//		
//		return rotation;
	}
	
	private double getMagField(StarTypeData data)
	{
		double maxMag = data.getMaxMagField();
		double minMag = data.getMinMagField();
		double magRange = maxMag - minMag;
		
		double magField = rand.nextDouble()*magRange+minMag;
		return magField;
		
//		switch (type) {
//		case NEUTRON:
//			maxMag = EStarType.NEUTRON.getMaxMag();
//			minMag = EStarType.NEUTRON.getMinMag();
//			magRange = maxMag - minMag;			
//			magField = rand.nextDouble()*magRange+minMag;
//			break;
//		case BLACKHOLE:
//			maxMag = EStarType.BLACKHOLE.getMaxMag();
//			minMag = EStarType.BLACKHOLE.getMinMag();
//			magRange = maxMag - minMag;			
//			magField = rand.nextDouble()*magRange+minMag;
//			break;
//		case DWARF_WHITE:
//			double coinFlip = rand.nextDouble();
//			if (coinFlip < 0.04) //Only a few percent of white dwarfs have detectable fields
//				magField = (rand.nextDouble()*9999.0+1.0)*Math.pow(10, 5);
//			else {
//				maxMag = EStarType.DWARF_WHITE.getMaxMag();
//				minMag = EStarType.DWARF_WHITE.getMinMag();
//				magRange = maxMag - minMag;			
//				magField = rand.nextDouble()*magRange+minMag;				
//			}
//			break;
//		default:
//			maxMag = EStarType.MS_BLUE.getMaxMag();
//			minMag = EStarType.MS_BLUE.getMinMag();
//			magRange = maxMag - minMag;			
//			magField = rand.nextDouble()*magRange+minMag;
//			break;
//		}		
//		return magField;
//		
	}
	
	//QQQ StarMods should function the same as other mods--attached to a model, provide specific functions, etc.
	//Implement StarMods as an interface?  IStarMod?
//	private ArrayList<EStarMods> getStability(StarTypeData data)
//	{
//		double coin2 = rand.nextDouble();
//		
//		EStarType type = star.getType();
//		ArrayList<EStarMods> mods = new ArrayList<EStarMods>();
//		
//		switch (type) {
//		case MS_RED:
//			if ((coin2 >= 0.0) && (coin2 < 0.08))
//				mods.add(EStarMods.FLARE);
//			else
//				mods.add(EStarMods.NONE);
//			break;
//		case MS_ORANGE:
//			if ((coin2 > 0.0) && (coin2 < 0.02))
//				mods.add(EStarMods.FLARE);
//			else
//				mods.add(EStarMods.NONE);
//			break;
//		case MS_YELLOW:
//			if ((coin2 > 0.0) && (coin2 < 0.001))
//				mods.add(EStarMods.FLARE);
//			else
//				mods.add(EStarMods.NONE);
//			break;
//		case DWARF_WHITE:
//			if (coin2 < 0.0001)
//				mods.add(EStarMods.NONE);
//			else
//				mods.add(EStarMods.NONE);
//				//mods.add(EStarMods.WHITE_DWARF_NOVA);
//			break;
//		case SUPERGIANT:
//			if (coin2 < 0.0005)
//				mods.add(EStarMods.SUPERNOVA);
//			else
//				mods.add(EStarMods.NONE);
//			break;
//		case HYPERGIANT:
//			if (coin2 < 0.0005)
//				mods.add(EStarMods.SUPERNOVA);
//			else
//				mods.add(EStarMods.NONE);
//			break;
//		case NEUTRON:
//			if (coin2 < 0.75)
//				mods.add(EStarMods.STARQUAKE);
//			else
//				mods.add(EStarMods.NONE);
//			break;
//		case T_TAURI:
//			if (coin2 < 0.95)
//				mods.add(EStarMods.FLARE);
//			else
//				mods.add(EStarMods.NONE);
//			break;
//		default:
//			mods.add(EStarMods.NONE);
//			break;
//		}
//						
//		return mods;
//	}
	
	private double getAge(double lifeTime) {
		Random rand2 = new Random();
		
		if (lifeTime < Math.pow(10, 9)) {
			return lifeTime/(rand2.nextDouble()*2+1);
		}
		else if ((lifeTime < Constants.AgeOfUniverse) && (lifeTime >= Math.pow(10, 9))) {
			return lifeTime/(rand2.nextDouble()*2+1);//(rand2.nextDouble()*8+1.1);
		}
		else /*if (lifeTime >= Constants.AgeOfUniverse) */ {
			return Constants.AgeOfUniverse/(rand2.nextDouble()*2+1);//(rand2.nextDouble()*8+1.1);
		}
	}
	
	
}
